<html>
<head><meta charset="utf-8"><title>repr(transparent) struct optimization · t-compiler/wg-mir-opt · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/index.html">t-compiler/wg-mir-opt</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html">repr(transparent) struct optimization</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="245476720"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245476720" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Simon Vandel Sillesen <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245476720">(Jul 09 2021 at 18:00)</a>:</h4>
<p>Reading  <a href="#narrow/stream/122651-general/topic/does.20Repr.28C.29.20on.20a.20single.20field.20struct.20hurts.20optimizations.3F">https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/does.20Repr.28C.29.20on.20a.20single.20field.20struct.20hurts.20optimizations.3F</a> I was wondering why the layout of a transparent Wrapper struct is not the same as the wrapped type.<br>
Example: <a href="https://godbolt.org/z/PEc9Pc6Kc">https://godbolt.org/z/PEc9Pc6Kc</a></p>
<p>What am I missing that makes rustc not make any #[repr(transparent)] struct have the same layout as the wrapped type?</p>



<a name="245479754"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245479754" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> erikdesjardins <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245479754">(Jul 09 2021 at 18:26)</a>:</h4>
<p>i believe that would be legal and beneficial, although i'm not intricately familar with layout</p>
<p>i tried doing it myself a while ago but i ran into trouble<br>
nothing fundamental but it was more annoying than i expected to just "forward" the layout to another type (i think...)</p>



<a name="245480113"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245480113" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Simon Vandel Sillesen <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245480113">(Jul 09 2021 at 18:29)</a>:</h4>
<p>Do you by chance have your work anywhere? Unless it is in fact illegal, I would like to attempt this</p>



<a name="245480178"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245480178" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> erikdesjardins <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245480178">(Jul 09 2021 at 18:29)</a>:</h4>
<p>i never pushed it, i'll see if i can find it in the reflog</p>



<a name="245483550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245483550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> erikdesjardins <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245483550">(Jul 09 2021 at 18:58)</a>:</h4>
<p>can't find it, it must have been too long ago, sorry<br>
i didn't get that much done tbh, maybe 20-30 lines</p>
<p>that said...</p>
<p>currently, structs with one non-zst field are given scalar/scalarpair/vector layout here<br>
<a href="https://github.com/rust-lang/rust/blob/619c27a53959e2d79aadb01cba5b2c49756df771/compiler/rustc_middle/src/ty/layout.rs#L923-L977">https://github.com/rust-lang/rust/blob/619c27a53959e2d79aadb01cba5b2c49756df771/compiler/rustc_middle/src/ty/layout.rs#L923-L977</a><br>
and especially here<br>
<a href="https://github.com/rust-lang/rust/blob/619c27a53959e2d79aadb01cba5b2c49756df771/compiler/rustc_middle/src/ty/layout.rs#L436-L455">https://github.com/rust-lang/rust/blob/619c27a53959e2d79aadb01cba5b2c49756df771/compiler/rustc_middle/src/ty/layout.rs#L436-L455</a><br>
so handling repr(transparent) nearby would make sense<br>
(hmm, we could probably do this for all repr(Rust) structs with 1 non-zst field, not just repr(transparent)...)</p>
<p>you may also need to change this function to not create a GEP when accessing the non-zst field of a repr(transparent) struct (or something)<br>
<a href="https://github.com/rust-lang/rust/blob/619c27a53959e2d79aadb01cba5b2c49756df771/compiler/rustc_codegen_ssa/src/mir/place.rs#L86">https://github.com/rust-lang/rust/blob/619c27a53959e2d79aadb01cba5b2c49756df771/compiler/rustc_codegen_ssa/src/mir/place.rs#L86</a></p>



<a name="245485177"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245485177" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Simon Vandel Sillesen <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245485177">(Jul 09 2021 at 19:14)</a>:</h4>
<p>Thanks for the links! <br>
I'll try to tackle structs that are specified as transparent by the user first. Inferring which structs can be automatically treated as transparent could be a next thing.</p>
<p>If I just wanted to make the layout of a repr-transparent struct be the layout as the only field, can't I just do a early return of "evaluate the layout of the inner Ty"  somewhere around here? <a href="https://github.com/rust-lang/rust/blob/ac6e239b3bdc7b05b160f8431f17f53ba4d84c86/compiler/rustc_middle/src/ty/layout.rs#L895-L895">https://github.com/rust-lang/rust/blob/ac6e239b3bdc7b05b160f8431f17f53ba4d84c86/compiler/rustc_middle/src/ty/layout.rs#L895-L895</a></p>



<a name="245503730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245503730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Simon Vandel Sillesen <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245503730">(Jul 09 2021 at 21:30)</a>:</h4>
<p>Yeah so I got a bit stuck. Not sure where the best place would be to transform the transparent-struct. Things I have considered</p>
<ul>
<li>It seems like both the layout and the AdtDef needs to be adjusted, as otherwise MIR building will create field projections that try to access the  wrapped value. But not really sure what to transform the AdtDef as if the inner type is not an ADT (e.g primitive)</li>
<li>somehow "transmute" the type of repr-transparent struct to the type of the inner type. This can only happen after type-checking is done, which I'm not sure it is. In the case of Wrapper(usize), all uses of Wrapper would be a TyKind::Uint instead. I don't know the consequences of this, but then layout calculation comes "for free".</li>
</ul>



<a name="245674947"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245674947" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245674947">(Jul 12 2021 at 11:46)</a>:</h4>
<p>Since we are solely talking about codegen, I think we could do this as an optimization that replaces all locals of <code>repr(transparent)</code> type with their first field and removes the field projection from all projections on such types</p>



<a name="245674997"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245674997" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245674997">(Jul 12 2021 at 11:47)</a>:</h4>
<p>This would mean that MIR would stop seeing <em>any</em> <code>repr(transparent)</code> types, but only at the point where all typeck, borrowck and other analyses are done</p>



<a name="245675013"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245675013" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245675013">(Jul 12 2021 at 11:47)</a>:</h4>
<p>so the language is not affected, but optimizations and codegen are</p>



<a name="245677349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245677349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245677349">(Jul 12 2021 at 12:13)</a>:</h4>
<p>This sounds like a special case of SRoA, thuogh I guess whatever you're proposing would work across call boundaries, whereas SROA generally doesn't</p>



<a name="245684845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/189540-t-compiler/wg-mir-opt/topic/repr%28transparent%29%20struct%20optimization/near/245684845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/189540-t-compiler/wg-mir-opt/topic/repr(transparent).20struct.20optimization.html#245684845">(Jul 12 2021 at 13:20)</a>:</h4>
<p>yea... function call signatures would still contain such types, and would have to be cleaned before using them in MIR, so it's not as solid as I thought</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>